package com.itheima.framework;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Configuration {
    private String url;
    private String driver;
    private String username;
    private String password;

    private Map<String, Mapper> mapperMap = new HashMap<>();

    public Configuration(String fileName) {
        InputStream inputStream = Configuration.class.getResourceAsStream("/" + fileName);

        try {
            Document document = new SAXReader().read(inputStream);
            loadMyBatisConfig(document);

            loadMapper(document);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    private void loadMapper(Document document) throws DocumentException {
        // 1. 获取mapper元素
        Node node = document.selectSingleNode("//mapper");
        // 2. 类型转换
        Element element = (Element) node;
        // 3. 获取resource属性值
        String mapperPath = element.attributeValue("resource");
        // 4. 加载映射文件为输入流
        InputStream inputStream = Configuration.class.getResourceAsStream("/" + mapperPath);
        // 5. 利用dom4j解析UserMapper.xml文件的输入流
        Document mapperDocument = new SAXReader().read(inputStream);
        // 6. 获取根元素
        Element rootElement = mapperDocument.getRootElement();
        // 7. 获取namespace的值
        String namespace = rootElement.attributeValue("namespace");
        // 8. 获取select子标签
        Element select = rootElement.element("select");
        // 9. 获取id属性值
        String id = select.attributeValue("id");
        // 10. 获取resultType属性值
        String resultType = select.attributeValue("resultType");
        // 11. 获取sql
        String sql = select.getTextTrim();
        // 12. 创建Mapper对象
        Mapper mapper = new Mapper(namespace, id, resultType, sql);

        // 13. 保存Mapper对象到成员属性中
        mapperMap.put(namespace + "." + id, mapper);
    }

    private void loadMyBatisConfig(Document document) {
        final List<Node> nodes = document.selectNodes("//property");
        for (Node node : nodes) {
            Element element = (Element) node;
            final String name = element.attributeValue("name");
            final String value = element.attributeValue("value");
            switch (name) {
                case "url":
                    this.url = value;
                    break;
                case "driver":
                    this.driver = value;
                    break;
                case "username":
                    this.username = value;
                    break;
                case "password":
                    this.password = value;
                    break;
            }
        }
    }

    @Override
    public String toString() {
        return "Configuration{" +
                "url='" + url + '\'' +
                ", driver='" + driver + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", mapperMap=" + mapperMap +
                '}';
    }

    public Map<String, Mapper> getMapperMap() {
        return mapperMap;
    }

    public void setMapperMap(Map<String, Mapper> mapperMap) {
        this.mapperMap = mapperMap;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
